home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Source Code / Visual Basic Source Code.iso / vbsource / 256pb2 / dib.c < prev    next >
C/C++ Source or Header  |  1992-03-12  |  14KB  |  428 lines

  1. //-----------------------------------------------------------------------------
  2. // DIB.C
  3. //
  4. // This is a collection of useful DIB manipulation/information gathering
  5. // functions.  Many functions are supplied simply to take the burden
  6. // of taking into account whether a DIB is a Win30 style or OS/2 style
  7. // DIB away from the application.
  8. //
  9. // The functions in this module assume that the DIB pointers or handles
  10. // passed to them point to a block of memory in one of two formats:
  11. //
  12. //       a) BITMAPINFOHEADER + color table + DIB bits (3.0 style DIB)
  13. //       b) BITMAPCOREHEADER + color table + DIB bits (OS/2 PM style)
  14. //
  15. // The SDK Reference, Volume 2 describes these data structures.
  16. //
  17. // A number of functions in this module were lifted from SHOWDIB,
  18. // and modified to handle OS/2 DIBs.
  19. //
  20. // The functions in this module could be streamlined (made faster and
  21. // smaller) by removing the OS/2 DIB specific code, and assuming all
  22. // DIBs passed to it are Win30 style DIBs.  The DIB file reading code
  23. // would need to be modified to always convert DIBs to Win30 style
  24. // DIBs.  The only reason this isn't done in DIBView is because DIBView
  25. // was written to test display and printer drivers (which are supposed
  26. // to support OS/2 DIBs wherever they support Win30 style DIBs).  SHOWDIB
  27. // is a great example of how to go about doing this.
  28. //-----------------------------------------------------------------------------
  29.  
  30. #include <windows.h>
  31. #include <memory.h>
  32. #include "errors.h"
  33. #include "dib.h"
  34.  
  35. //---------------------------------------------------------------------
  36. //
  37. // Function:   FindDIBBits
  38. //
  39. // Purpose:    Given a pointer to a DIB, returns a pointer to the
  40. //             DIB's bitmap bits.
  41. //
  42. // Parms:      lpbi == pointer to DIB header (either BITMAPINFOHEADER
  43. //                       or BITMAPCOREHEADER)
  44. //
  45. // History:   Date      Reason
  46. //             6/01/91  Created
  47. //
  48. //---------------------------------------------------------------------
  49.  
  50. LPSTR FAR PASCAL FindDIBBits (LPSTR lpbi)
  51. {
  52.    return (lpbi + *(LPDWORD)lpbi + PaletteSize (lpbi));
  53. }
  54.  
  55. //---------------------------------------------------------------------
  56. //
  57. // Function:   DIBNumColors
  58. //
  59. // Purpose:    Given a pointer to a DIB, returns a number of colors in
  60. //             the DIB's color table.
  61. //
  62. // Parms:      lpbi == pointer to DIB header (either BITMAPINFOHEADER
  63. //                       or BITMAPCOREHEADER)
  64. //
  65. // History:   Date      Reason
  66. //             6/01/91  Created
  67. //
  68. //---------------------------------------------------------------------
  69.  
  70. WORD FAR PASCAL DIBNumColors (LPSTR lpbi)
  71. {
  72.    WORD wBitCount;
  73.  
  74.  
  75.       // If this is a Windows style DIB, the number of colors in the
  76.       //  color table can be less than the number of bits per pixel
  77.       //  allows for (i.e. lpbi->biClrUsed can be set to some value).
  78.       //  If this is the case, return the appropriate value.
  79.  
  80.    if (IS_WIN30_DIB (lpbi))
  81.       {
  82.       DWORD dwClrUsed;
  83.  
  84.       dwClrUsed = ((LPBITMAPINFOHEADER) lpbi)->biClrUsed;
  85.  
  86.       if (dwClrUsed)
  87.          return (WORD) dwClrUsed;
  88.       }
  89.  
  90.  
  91.       // Calculate the number of colors in the color table based on
  92.       //  the number of bits per pixel for the DIB.
  93.  
  94.    if (IS_WIN30_DIB (lpbi))
  95.       wBitCount = ((LPBITMAPINFOHEADER) lpbi)->biBitCount;
  96.    else
  97.       wBitCount = ((LPBITMAPCOREHEADER) lpbi)->bcBitCount;
  98.  
  99.    switch (wBitCount)
  100.       {
  101.       case 1:
  102.          return 2;
  103.  
  104.       case 4:
  105.          return 16;
  106.  
  107.       case 8:
  108.          return 256;
  109.  
  110.       default:
  111.          return 0;
  112.       }
  113. }
  114.  
  115. //---------------------------------------------------------------------
  116. //
  117. // Function:   PaletteSize
  118. //
  119. // Purpose:    Given a pointer to a DIB, returns number of bytes
  120. //             in the DIB's color table.
  121. //
  122. // Parms:      lpbi == pointer to DIB header (either BITMAPINFOHEADER
  123. //                       or BITMAPCOREHEADER)
  124. //
  125. // History:   Date      Reason
  126. //             6/01/91  Created
  127. //
  128. //---------------------------------------------------------------------
  129.  
  130. WORD FAR PASCAL PaletteSize (LPSTR lpbi)
  131. {
  132.    if (IS_WIN30_DIB (lpbi))
  133.       return (DIBNumColors (lpbi) * sizeof (RGBQUAD));
  134.    else
  135.       return (DIBNumColors (lpbi) * sizeof (RGBTRIPLE));
  136. }
  137.  
  138. //---------------------------------------------------------------------
  139. //
  140. // Function:   CreateDIBPalette
  141. //
  142. // Purpose:    Given a handle to a DIB, constructs a logical palette,
  143. //             and returns a handle to this palette.
  144. //
  145. //             Stolen almost verbatim from ShowDIB.
  146. //
  147. // Parms:      hDIB == HANDLE to global memory with a DIB header
  148. //                     (either BITMAPINFOHEADER or BITMAPCOREHEADER)
  149. //
  150. // History:   Date      Reason
  151. //             6/01/91  Created
  152. //
  153. //---------------------------------------------------------------------
  154.  
  155. HPALETTE FAR PASCAL CreateDIBPalette (HANDLE hDIB)
  156. {
  157.    LPLOGPALETTE     lpPal;
  158.    HANDLE           hLogPal;
  159.    HPALETTE         hPal = NULL;
  160.    int              i, wNumColors;
  161.    LPSTR            lpbi;
  162.    LPBITMAPINFO     lpbmi;
  163.    LPBITMAPCOREINFO lpbmc;
  164.    BOOL             bWinStyleDIB;
  165.  
  166.    if (!hDIB)
  167.       return NULL;
  168.  
  169.    lpbi         = GlobalLock (hDIB);
  170.    lpbmi        = (LPBITMAPINFO) lpbi;
  171.    lpbmc        = (LPBITMAPCOREINFO) lpbi;
  172.    wNumColors   = DIBNumColors (lpbi);
  173.    bWinStyleDIB = IS_WIN30_DIB (lpbi);
  174.  
  175.    if (wNumColors)
  176.       {
  177.       hLogPal = GlobalAlloc (GHND, sizeof (LOGPALETTE) +
  178.                              sizeof (PALETTEENTRY) * wNumColors);
  179.  
  180.       if (!hLogPal)
  181.          {
  182.          DIBError (ERR_CREATEPAL);
  183.          GlobalUnlock (hDIB);
  184.          return NULL;
  185.          }
  186.  
  187.       lpPal = (LPLOGPALETTE) GlobalLock (hLogPal);
  188.  
  189.       lpPal->palVersion    = PALVERSION;
  190.       lpPal->palNumEntries = wNumColors;
  191.  
  192.       for (i = 0;  i < wNumColors;  i++)
  193.          {
  194.          if (bWinStyleDIB)
  195.             {
  196.             lpPal->palPalEntry[i].peRed   = lpbmi->bmiColors[i].rgbRed;
  197.             lpPal->palPalEntry[i].peGreen = lpbmi->bmiColors[i].rgbGreen;
  198.             lpPal->palPalEntry[i].peBlue  = lpbmi->bmiColors[i].rgbBlue;
  199.             lpPal->palPalEntry[i].peFlags = 0;
  200.             }
  201.          else
  202.             {
  203.             lpPal->palPalEntry[i].peRed   = lpbmc->bmciColors[i].rgbtRed;
  204.             lpPal->palPalEntry[i].peGreen = lpbmc->bmciColors[i].rgbtGreen;
  205.             lpPal->palPalEntry[i].peBlue  = lpbmc->bmciColors[i].rgbtBlue;
  206.             lpPal->palPalEntry[i].peFlags = 0;
  207.             }
  208.          }
  209.  
  210.       hPal = CreatePalette (lpPal);
  211.  
  212.       if (!hPal)
  213.          DIBError (ERR_CREATEPAL);
  214.  
  215.       GlobalUnlock (hLogPal);
  216.       GlobalFree   (hLogPal);
  217.    }
  218.  
  219.    GlobalUnlock (hDIB);
  220.  
  221.    return hPal;
  222. }
  223.  
  224. //---------------------------------------------------------------------
  225. //
  226. // Function:   DIBHeight
  227. //
  228. // Purpose:    Given a pointer to a DIB, returns its height.  Note
  229. //             that it returns a DWORD (since a Win30 DIB can have
  230. //             a DWORD in its height field), but under Win30, the
  231. //             high order word isn't used!
  232. //
  233. // Parms:      lpDIB == pointer to DIB header (either BITMAPINFOHEADER
  234. //                       or BITMAPCOREHEADER)
  235. //
  236. // History:   Date      Reason
  237. //             6/01/91  Created
  238. //
  239. //---------------------------------------------------------------------
  240.  
  241. DWORD FAR PASCAL DIBHeight (LPSTR lpDIB)
  242. {
  243.    LPBITMAPINFOHEADER lpbmi;
  244.    LPBITMAPCOREHEADER lpbmc;
  245.  
  246.    lpbmi = (LPBITMAPINFOHEADER) lpDIB;
  247.    lpbmc = (LPBITMAPCOREHEADER) lpDIB;
  248.  
  249.    if (lpbmi->biSize == sizeof (BITMAPINFOHEADER))
  250.       return lpbmi->biHeight;
  251.    else
  252.       return (DWORD) lpbmc->bcHeight;
  253. }
  254.  
  255. //---------------------------------------------------------------------
  256. //
  257. // Function:   DIBWidth
  258. //
  259. // Purpose:    Given a pointer to a DIB, returns its width.  Note
  260. //             that it returns a DWORD (since a Win30 DIB can have
  261. //             a DWORD in its width field), but under Win30, the
  262. //             high order word isn't used!
  263. //
  264. // Parms:      lpDIB == pointer to DIB header (either BITMAPINFOHE